昨天設定完關鍵字搜尋後,覺得我這部份的需求沒有定義得很明確!
導致 index 的程式碼沒有很接近我的需求想像。
雖然這次的挑戰是前後端分離,沒有帶入前端,但根據昨天的關鍵字搜尋設定,可以想像出前端可能需要兩個關鍵字輸入方框,並且也沒有辦法查詢所有產品,這樣也並不符合我想要的使用者體驗。
今天再重新梳理關鍵字搜尋的需求並進行修正,然後一併加入排序機制!GO~
線上產品瀏覽系統裡除了甜點,還會有茶品類,品項可能會有好幾種,產品敘述也各不相同,可以再自己設定其他類別的產品。
在線上菜單系統裡只有「一個」輸入方框,能在這個方框裡輸入關鍵字進行搜尋。
因為每個人的直觀想法不同,如果對於關鍵字沒有定義,會增加搜尋困難度,但如果拆解成每一個字進行搜尋,可能也無法精準搜尋產品,降低使用者體驗。
所以我會將前端的輸入方框定義為:品名搜尋
讓使用者直觀想到:「這個搜尋方框是用來搜尋品名的」,引導使用者輸入與品名相關的關鍵字。
例如:紅茶、杏仁瓦片等等。
假設我希望能搜尋所有紅茶讓我挑選,所以我會在方框裡直觀的輸入:「紅茶」,按下按鈕進行搜尋後,則需要將與「紅茶」所有相關產品都列出!並且列表第一個需顯示最新上架的產品。
如果方框內沒有值,則列出所有產品。
限制方框裡僅能輸入 10 個字以內,並只接受繁體中文,不接受其他語言。
public function index(Request $request)
{
// 驗證輸入的關鍵字是否符合規則:限制輸入 10 個字以內,並只接受繁體中文
$validator = Validator::make($request->all(), [
'keyword' => 'nullable|string|max:10|regex:/^[\p{Han}]+$/u',
]);
// 如果驗證失敗,回傳錯誤訊息
if ($validator->fails()) {
return response()->json([
'message' => '請重新輸入!',
'errors' => $validator->errors(),
], Response::HTTP_BAD_REQUEST); // 回傳 HTTP 400 錯誤
}
// 取得查詢關鍵字
$keyword = $request->input('keyword');
// 如果有關鍵字,執行關鍵字搜尋,否則列出所有產品
if ($keyword) {
$products = Product::where('product_name', 'LIKE', "%$keyword%")
->orWhere('product_description', 'LIKE', "%$keyword%")
->orderBy('created_at', 'desc') // 按照最新上架的產品排序
->paginate(10); // 固定每頁 10 筆資料
} else {
// 沒有關鍵字時列出所有產品
$products = Product::orderBy('created_at', 'desc') // 按照最新上架的產品排序
->paginate(10); // 固定每頁 10 筆資料
}
// 回傳產品列表
return response()->json($products);
}
主要是將多個查詢條件結合在一起。
當你想要添加一個「或」的條件時,就可以使用 orWhere。
如果第一個條件不成立,則檢查第二個條件。
$products = Product::where('product_name', 'LIKE', "%$keyword%")
->orWhere('product_description', 'LIKE', "%$keyword%")
->orderBy('created_at', 'desc') // 按照最新上架的產品排序
->paginate(10); // 固定每頁 10 筆資料
這是查詢的起點,我們使用 where 來設定第一個條件:產品名稱包含特定的關鍵字。
表示我們要查詢 product_name 字段中包含關鍵字的產品。
LIKE 用於模糊查詢,% 表示任意數量的字符。
將另一個條件加進來,如果第一個條件不滿足,則檢查第二個條件:產品描述是否包含相同的關鍵字。
主要是對查詢結果進行排序:可以根據指定的欄位對資料進行升序或降序排列。
無論是單一欄位還是多個欄位的排序都可以。
$query->orderBy('column', 'direction');
column:你想要排序的欄位名稱。例如:created_at、price 等。
direction:排序的方向,可以是 'asc'(升序)或 'desc'(降序)。
升序是從小到大,降序則是從大到小。
對多個欄位進行排序。
假設我們希望先依 type_id 進行「升序」排序,再依 price 進行「降序」排序:
$products = Product::orderBy('type_id', 'asc')
->orderBy('price', 'desc')
->get();
顯示「產品名稱」及「產品敘述」包含「紅茶」關鍵字的所有產品,並以最新上架日期進行排序。即為測試成功!
顯示設定好的錯誤訊息,即為測試成功!
顯示所有產品,並以最新上架日期進行排序,即為測試成功!